package com.black.utils.network.transmit.udp;

import com.black.utils.commons.pool.PoolProperties;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.*;

/**
 * 无连接通讯
 *
 * @author ylx
 */
@Slf4j
public class UDPClient {
    private final DatagramSocket socket;
    private final PoolProperties properties;
    private static final int MAX_LEN = 1024;
    private static final byte[] BUFFER = new byte[MAX_LEN];

    public UDPClient(PoolProperties properties) throws SocketException {
        this.socket = new DatagramSocket();
        this.properties = properties;
        this.socket.setSoTimeout(properties.getTimeout());
    }

    public boolean send(String message) {
        return send(message, properties.getIp());
    }

    public boolean send(String message, String host) {
        return send(message, host, properties.getPort());
    }

    public boolean send(String message, String host, int port) {
        try {
            byte[] buffer = message.getBytes();
            if (buffer.length > MAX_LEN) {
                log.error("Message too long: " + message);
                return false;
            }
            InetAddress address = InetAddress.getByName(host);
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);
            socket.send(packet);
            String response = response();
            if (response == null) {
                log.error("No response received from server.");
                return false;
            }
            return true;
        } catch (UnknownHostException e) {
            log.error("Unknown host: " + properties.getIp());
        } catch (IOException e) {
            log.error("Error sending message: " + e.getMessage());
        }
        return false;
    }

    public String response() throws IOException {
        DatagramPacket responsePacket = new DatagramPacket(BUFFER, BUFFER.length);
        socket.receive(responsePacket);
        return new String(responsePacket.getData());
    }

    public void close() {
        socket.disconnect();
        socket.close();
    }
}
